#if !defined(MTX_UTILITY_H)
#define MTX_UTILITY_H

#include "mtx/types.h"
#include <iostream>
#include <iomanip>

namespace mtx {

template <class V>
void tracevec(const V & v) {
	std::cout << std::endl;
	int def_prec = std::cout.precision(3);
	size_type i;
	for (i = 0; i < v.size(); ++i)
		std::cout << "  |\t" << v(i) << "\t|\n";
	std::cout << std::endl;
	std::cout.precision(def_prec);
}


template <class M>
void tracemat(const M & m) {
	std::cout << std::endl;
	int def_prec = std::cout.precision(3);
	size_type i, j;
	for (i = 0; i < m.rows(); ++i) {
		std::cout << "  |";
		for (j = 0; j < m.cols(); ++j) {
			std::cout << "\t" << m(i, j);
		}
		std::cout << "\t|\n";
	}
	std::cout << std::endl;
	std::cout.precision(def_prec);
}

template <class T>
std::ostream & operator << (std::ostream & out, const matrix<T> & m) {
	out << std::endl;
	size_type i, j, p = out.precision(3);
	for (i = 0; i < m.rows(); ++i) {
		out << "|";
		for (j = 0; j < m.cols(); ++j) {
			out << " " << std::setw(10) << m(i, j);
		}
		out << " |\n";
	}
	out.precision(p);
	return out;
}

template <class T>
std::ostream & operator << (std::ostream & out, const vector<T> & v) {
	out << std::endl;
	size_type i, p = out.precision(3);
	for (i = 0; i < v.size(); ++i)
		out << "| " << std::setw(10) << v(i) << " |\n";
	out.precision(p);
	return out;
}

} // mtx

#endif   // MTX_UTILITY_H
